﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Collections;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using LitJson;
using System.Text.RegularExpressions;
using System.Management;

namespace CloseAllWindows
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public static MainWindow Instance = null;
        public Dictionary<string, List<ProcessInfo>> ProcessInfoDic = new Dictionary<string, List<ProcessInfo>>();
        public Dictionary<string, ProcessGroupControl> ProcessGroupControlDic = new Dictionary<string, ProcessGroupControl>();
        public Dictionary<string, List<ProcessItemControl>> ProcessItemControlDic = new Dictionary<string, List<ProcessItemControl>>();
        public MainWindow()
        {
            InitializeComponent();
            Instance = this;
            InitProcessInfo();
            InitProcessList();
        }
        void InitProcessInfo()
        {
            string strConfigInfo = "";
            Utility.ReadFileString("./CloseConfig.json", ref strConfigInfo);
            JsonData jsonData = JsonMapper.ToObject(strConfigInfo);
            Process[] pslist = Process.GetProcesses();
            List<string> IgnoreConfig = JsonMapper.ToObject<List<string>>(jsonData["Ignore"].ToJson());
            List<string> ForceCloseConfig = JsonMapper.ToObject<List<string>>(jsonData["ForceClose"].ToJson());
            foreach (var ps in pslist)
            {
                if (String.IsNullOrEmpty(ps.MainWindowTitle) || ps.StartInfo.WindowStyle != ProcessWindowStyle.Normal)
                    continue;

                string processGroup = "Unknown";
                if (false == String.IsNullOrEmpty(ps.ProcessName))
                {
                    processGroup = ps.ProcessName;
                }
                if (ps.Id == Process.GetCurrentProcess().Id)
                    continue;
                //挂起的
                if (ps.Responding == false)
                    continue;
                if (IgnoreConfig.Contains(processGroup))
                    continue;

                ProcessInfo psInfo = new ProcessInfo();
                psInfo.process = ps;
                psInfo.isSelected = true;
                psInfo.isCanForceClose = ForceCloseConfig.Contains(processGroup);
                if (false == ProcessInfoDic.ContainsKey(processGroup))
                {
                    ProcessInfoDic.Add(processGroup, new List<ProcessInfo>());
                }
                ProcessInfoDic[processGroup].Add(psInfo);
            }
        }
        bool ProcessItemFilter(object item)
        {
            string strMatchInfo = "";
            string strGroupInfo = "";
            if (item is ProcessGroupControl)
            {
                ProcessGroupControl checkItem = item as ProcessGroupControl;
                strGroupInfo = checkItem.GroupName;
                try
                {
                    if (String.IsNullOrEmpty(FilterInput.Text) || Regex.IsMatch(strGroupInfo, FilterInput.Text, RegexOptions.IgnoreCase))
                    {
                        return true;
                    }
                }
                catch
                {
                    return false;
                }
                if (ProcessItemControlDic.ContainsKey(checkItem.GroupName))
                {
                    foreach (var itemControl in ProcessItemControlDic[checkItem.GroupName])
                    {
                        strMatchInfo = itemControl.ItemLabel.Content.ToString();
                        strGroupInfo = itemControl.GroupName;
                        try
                        {
                            if (String.IsNullOrEmpty(FilterInput.Text) || String.IsNullOrEmpty(strMatchInfo) || Regex.IsMatch(strMatchInfo, FilterInput.Text, RegexOptions.IgnoreCase) || Regex.IsMatch(strGroupInfo, FilterInput.Text, RegexOptions.IgnoreCase))
                            {
                                return true;
                            }
                        }
                        catch
                        {
                            return false;
                        }
                    }
                }
            }
            else if (item is ProcessItemControl)
            {
                ProcessItemControl checkItem = item as ProcessItemControl;
                strMatchInfo = checkItem.ItemLabel.Content.ToString();
                strGroupInfo = checkItem.GroupName;
                try
                {
                    if (String.IsNullOrEmpty(FilterInput.Text) || String.IsNullOrEmpty(strMatchInfo) || Regex.IsMatch(strMatchInfo, FilterInput.Text, RegexOptions.IgnoreCase) || Regex.IsMatch(strGroupInfo, FilterInput.Text, RegexOptions.IgnoreCase))
                    {
                        return true;
                    }
                }
                catch
                {
                    return false;
                }
            }

            return false;
        }
        public ImageSource GetIcon(string fileName)
        {
            try
            {
                System.Drawing.Icon icon = System.Drawing.Icon.ExtractAssociatedIcon(fileName);
                return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                            icon.Handle,
                            new Int32Rect(0, 0, icon.Width, icon.Height),
                            BitmapSizeOptions.FromEmptyOptions());
            }
            catch
            {
                Debug.Print(string.Format("GetIcon Failed:[{0}]", fileName));
                return null;
            }

        }
        public BitmapImage UrlToImage(string iconname)
        {
            string path = string.Format("pack://application:,,,/Resources/{0}", iconname);
            BitmapImage img = new BitmapImage(); ;
            try
            {
                img.BeginInit();
                img.UriSource = new Uri(path);
                img.EndInit();
            }
            catch (Exception ex)
            {
                Debug.Print("UrlToImage:" + ex.Message);
                return null;
            }

            return img;
        }

        void InitProcessList()
        {
            foreach (var dict in ProcessInfoDic)
            {
                ProcessGroupControl groupControl = new ProcessGroupControl();
                groupControl.GroupName = dict.Key;
                groupControl.ItemCheck.IsChecked = true;
                groupControl.ItemGroup.Header = string.Format("     {0}", dict.Key);
                groupControl.ToolTip = dict.Key;
                ToolTipService.SetShowDuration(groupControl, 600000);
                groupControl.Focusable = false;
                ProcessList.Items.Add(groupControl);
                ProcessGroupControlDic.Add(dict.Key, groupControl);
                ProcessItemControlDic.Add(dict.Key, new List<ProcessItemControl>());
                for (int index = 0; index < dict.Value.Count; index++)
                {
                    ProcessInfo psInfo = dict.Value[index];
                    ProcessItemControl itemControl = new ProcessItemControl();
                    itemControl.GroupName = dict.Key;
                    itemControl.GroupIndex = index;
                    itemControl.ItemCheck.IsChecked = true;
                    itemControl.ItemLabel.Content = Regex.Replace(psInfo.process.MainWindowTitle, @"\s", "");
                    itemControl.ToolTip = psInfo.process.MainWindowTitle;
                    ImageSource iconImage = null;
                    //尝试从进程文件中读取icon信息
                    iconImage = GetIcon(ProcessUtilities.GetProcessFilePath(psInfo.process));
                    if (iconImage != null)
                    {
                        itemControl.ItemImage.Source = iconImage;
                    }
                    else
                    {
                        //读取失败 用默认图标
                        itemControl.ItemImage.Source = UrlToImage("default.png");
                    }
                    ToolTipService.SetShowDuration(itemControl, 600000);
                    itemControl.Focusable = false;
                    ProcessList.Items.Add(itemControl);
                    ProcessItemControlDic[dict.Key].Add(itemControl);
                }
            }
            ProcessList.Items.Filter = ProcessItemFilter;
        }


        private void Ok_Click(object sender, RoutedEventArgs e)
        {

            foreach (var dict in ProcessInfoDic)
            {
                for (int index = 0; index < dict.Value.Count; index++)
                {
                    var psinfo = dict.Value[index];
                    if (ProcessItemControlDic.ContainsKey(dict.Key) && false == ProcessItemControlDic[dict.Key][index].IsVisible)
                    {
                        continue;
                    }
                    if (psinfo.isSelected)
                    {
                        if (psinfo.isCanForceClose)
                        {
                            psinfo.process.Kill();
                        }
                        else
                        {
                            psinfo.process.CloseMainWindow();
                        }
                    }
                }
            }
            Close();
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
        private void Window_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == System.Windows.Input.Key.Escape)
            {
                Close();
            }
        }
        private void SelectAllOnChange()
        {
            foreach (var vaule in ProcessGroupControlDic.Values)
            {
                vaule.ItemCheck.IsChecked = SelectAll.IsChecked;
            }
        }
        private void SelectAll_Checked(object sender, RoutedEventArgs e)
        {
            SelectAllOnChange();
        }

        private void SelectAll_UnChecked(object sender, RoutedEventArgs e)
        {
            SelectAllOnChange();
        }

        private void FilterInput_TextChanged(object sender, TextChangedEventArgs e)
        {
            ProcessList.Items.Filter = ProcessItemFilter;
        }

        private void CMD_SeleAllChecked_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
        private void CMD_SeleAllChecked_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SelectAll.IsChecked = !SelectAll.IsChecked;
        }

        private void CMD_FocusFilterInput_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
        private void CMD_FocusFilterInput_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            FilterInput.Focus();
        }
    }
}
